package com.chen.nio;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioTest8 {

    public static void main(String[] args) throws Exception {
        // Opens a server-socket channel.
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //channel要和selector配合使用要将channel设置成非阻塞
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8888));
        Selector selector = Selector.open();
        //将channel注册到selector上，并且监控通道是否"接收就绪"
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("监听8888端口");

        while (true) {
            //阻塞到至少有一个通道在你注册的事件上就绪了，返回值表示的是有多少通道已经准备就绪
            int count = selector.select();
            System.out.println(count + "个通道已经准备就绪");
            //返回已选择键的集合
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                //表示通道已经有连接可以接受
                if (selectionKey.isAcceptable()) {
                    //返回这个key创建的channel
                    ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);
                    sc.register(selector, SelectionKey.OP_READ);
                    System.out.println("获得客户端的连接" + sc);
                } else if (selectionKey.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();

                    int byteRead = 0;
                    while (true) {
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        buffer.clear();
                        int read = socketChannel.read(buffer);
                        if (read <= 0) {
                            break;
                        }
                        buffer.flip();
                        socketChannel.write(buffer);
                        byteRead += read;
                    }
                    System.out.println("读取：" + byteRead + "，数据来自于" + socketChannel);

                } else if (selectionKey.isWritable()) {
                    System.out.println("Writable");
                }
                //将selectionKey从selector中移除，如果不移除，则一直会触发
                iterator.remove();
                System.out.println("selectionkey从channel中移除了");
            }

        }

    }
}
